#include "babl-internal.h"
#include "babl-db.h"
+static int babl_format_destruct (void *babl)
+{
+ BablFormat *format = babl;
+ if (format->image_template != NULL)
+ {
+ babl_set_destructor (format->image_template, NULL);
+ /* with no destructor set, the circular reference is no problem */
+ babl_free (format->image_template);
+ format->image_template = NULL;
+ }
+ return 0;
+}
+
static int
each_babl_format_destroy (Babl *babl,
void *data)
sizeof (BablType *) * (components) +
sizeof (int) * (components) +
sizeof (int) * (components));
+ babl_set_destructor (babl, babl_format_destruct);
babl->format.from_list = NULL;
babl->format.component = (void *) (((char *) babl) + sizeof (BablFormat));
#include "babl-internal.h"
+static int babl_image_destruct (void *babl)
+{
+ BablFormat *format = BABL (babl)->image.format;
+ if (format && format->image_template == NULL)
+ {
+ format->image_template = babl;
+ return -1; /* this should avoid freeing images created for formats,. */
+ }
+ return 0;
+}
+
static Babl *
image_new (BablFormat *format,
BablModel *model,
sizeof (void*) * (components) +
sizeof (int) * (components) +
sizeof (int) * (components));
+ babl_set_destructor (babl, babl_image_destruct);
babl->image.component = (void*)(((char *)babl) + sizeof (BablImage));
babl->image.sampling = (void*)(((char *)babl->image.component) + sizeof (BablComponent*) * (components));
babl->image.type = (void*)(((char *)babl->image.sampling) + sizeof (BablSampling*) * (components));
{
char *signature;
size_t size;
+ int (*destructor)(void *ptr);
} BablAllocInfo;
#define BABL_ALIGN 16
*((void **) ret - 1) = ret - BABL_ALLOC - offset;
BAI (ret)->signature = signature;
BAI (ret)->size = size;
+ BAI (ret)->destructor = NULL;
#if BABL_DEBUG_MEM
babl_mutex_lock (babl_debug_mutex);
mallocs++;
return (void *) (ret);
}
+/* set a callback to be called when the segment is freed.
+ */
+void
+babl_set_destructor (void *ptr,
+ int (*destructor)(void *ptr))
+{
+ babl_assert (IS_BAI (ptr));
+ BAI(ptr)->destructor = destructor;
+}
+
/* Create a duplicate allocation of the same size, note
* that the exact location of the allocation needs to be
* passed.
babl_free (void *ptr,
...)
{
- /* XXX:
- * Extra logic to make the bookeeping of BablImage cached
- * templates work out correctly, by using a babl_image_destroy
- * and custom destroy functions for babl_format this would be
- * avoided and the extra overhead not needed for non image/format
- * typed allocations.
- */
- if (BABL_IS_BABL (ptr))
- {
- switch (BABL (ptr)->instance.class_type)
- {
- case BABL_IMAGE:
- {
- BablFormat *format = BABL(ptr)->image.format;
- if (format)
- {
- if (format->image_template == NULL)
- {
- format->image_template = ptr;
- return;
- }
- else
- {
- }
- }
- }
- break;
- case BABL_FORMAT:
- {
- BablFormat *format = ptr;
- if (format->image_template != NULL)
- {
- BAI (format->image_template)->signature = NULL;
- free_f (BAI (format->image_template));
-#if BABL_DEBUG_MEM
- babl_mutex_lock (babl_debug_mutex);
- frees++;
- babl_mutex_unlock (babl_debug_mutex);
-#endif
- }
- format->image_template = NULL;
- }
- break;
- default:
- break;
- }
- }
+ functions_sanity ();
if (!ptr)
return;
if (!IS_BAI (ptr))
babl_fatal ("memory not allocated by babl allocator");
- functions_sanity ();
+
+ if (BAI (ptr)->destructor)
+ if (BAI (ptr)->destructor (ptr))
+ return; /* bail out on non 0 return from destructor */
+
BAI (ptr)->signature = NULL;
free_f (BAI (ptr));
#if BABL_DEBUG_MEM
typedef void (* BablFreeFunc) (void *ptr);
-void babl_set_malloc (BablMallocFunc malloc_function);
-void babl_set_free (BablFreeFunc free_function);
-int babl_memory_sanity (void);
-
-void * babl_malloc (size_t size);
-void babl_free (void *ptr,
- ...);
-void * babl_calloc (size_t nmemb,
- size_t size);
-void * babl_realloc (void *ptr,
- size_t size);
-
-size_t babl_sizeof (void *ptr);
-void * babl_dup (void *ptr);
-
-char * babl_strdup (const char *s);
-char * babl_strcat (char *dest,
- const char *src);
-
+void babl_set_malloc (BablMallocFunc malloc_function);
+void babl_set_free (BablFreeFunc free_function);
+int babl_memory_sanity (void);
+
+void * babl_malloc (size_t size);
+void babl_set_destructor (void *ptr,
+ int (*destructor)(void *ptr));
+
+void babl_free (void *ptr,
+ ...);
+void * babl_calloc (size_t nmemb,
+ size_t size);
+void * babl_realloc (void *ptr,
+ size_t size);
+
+size_t babl_sizeof (void *ptr);
+void * babl_dup (void *ptr);
+
+char * babl_strdup (const char *s);
+char * babl_strcat (char *dest,
+ const char *src);
#endif